Jeśli moja strona Ci pomogła, i chcesz aby była bardziej rozwijana, wesprzyj mnie buycoffee.to/madprojects

I. Wzorce kreacyjne
1. Singleton
2. Budowniczy
3. Prototyp
4. Fabryka
5. Fabryka abstrakcyjna
II. Wzorce strukturalne
1. Adapter
2. Most
3. Kompozyt
4. Dekorator
5. Fasada
6. Pyłek
7. Pełnomocnik
III. Wzorce czynnościowe
1. Łańcuch zobowiązań
2. Polecenie
3. Interpreter
4. Iterator
5. Mediator
6. Pamiątka
7. Obserwator
8. Stan
9. Strategia
10. Metoda szablonowa
11. Odwiedzający

Budowniczy (builder) - wzorzec projektowy (design pattern) - java

1. Cel:
Wzorzec projektowy Budowniczy (builder) ma za zadanie ukryć złożoność tworzenia obiektów.
Hermetyzuje i składa część złożonego obiektu w oddzielnym obiekcie konstruktora.

2. Problem:
Budowniczy jest używany aby oddzielić budowę złożonego obiektu od jego reprezentacji.
Proces budowy powoduje możliwość tworzenia różnych reprezentacji.
Mamy do wyboru wiele parametrów oraz możliwe że chcemy ostateczny obiekt mieć niezmienny (immutable).

3. Rozwiązanie:
A) budowniczy bandy czworga (Gang of Four)
Wzorzec konstruktora sugeruje wyodrębnienie kodu konstrukcji obiektu z jego własnej klasy
i przeniesienie go do oddzielnych obiektów zwanych konstruktorami.

B) Budowniczy metoda łańcuchowa :
Używamy statycznej wewnetrznej klasy (static inner class),
która ma za zadanie przekazać parametry do konstruktora naszej klasy.

4. Diagram klas wzorca Budowniczy:
A) wersja GoF (Gang of Four - bandy czworga):

B) wersja budowniczy metoda łańcuchowa (chaining):


5. Implementacja:
A) Budowniczy GoF
Kod operujący na wzorcu w celu uzyskania konkretnej klasy:
  1. public class Client {
  2.     public static void main (String[] args) {
  3.                 PizzaBuilder hawaiiPizzaBuilder = new HawaiiPizzaBuilder();
  4.                 Cook cook = new Cook(hawaiiPizzaBuilder);
  5.                 cook.buildPizza();
  6.                 Pizza hawaii = cook.getPizza();
  7.     }
  8. }
  9.  
Konkretna klasa którą chcemy uzyskąć:
  1. public class Pizza {
  2.         private String dough;
  3.         private String cheese;
  4.         private String ham;
  5.         private String vegetable;
  6.         private String fruit;
  7.         private String sauce;
  8.         private String toppings;
  9.        
  10.         public String getDough() {
  11.                 return dough;
  12.         }
  13.         public void setDough(String dough) {
  14.                 this.dough = dough;
  15.         }
  16.         public String getCheese() {
  17.                 return cheese;
  18.         }
  19.         public void setCheese(String cheese) {
  20.                 this.cheese = cheese;
  21.         }
  22.         public String getHam() {
  23.                 return ham;
  24.         }
  25.         public void setHam(String ham) {
  26.                 this.ham = ham;
  27.         }
  28.         public String getVegetable() {
  29.                 return vegetable;
  30.         }
  31.         public void setVegetable(String vegetable) {
  32.                 this.vegetable = vegetable;
  33.         }
  34.         public String getFruit() {
  35.                 return fruit;
  36.         }
  37.         public void setFruit(String fruit) {
  38.                 this.fruit = fruit;
  39.         }
  40.         public String getSauce() {
  41.                 return sauce;
  42.         }
  43.         public void setSauce(String sauce) {
  44.                 this.sauce = sauce;
  45.         }
  46.         public String getToppings() {
  47.                 return toppings;
  48.         }
  49.         public void setToppings(String toppings) {
  50.                 this.toppings = toppings;
  51.         }
  52. }
  53.  
Abstrakcyjna klasa budowniczego:
  1. public abstract class PizzaBuilder {
  2.     public Pizza getPizza () {
  3.         return pizza;
  4.     }
  5.  
  6.     private Pizza pizza =null;
  7.  
  8.     public HouseBuilder(){
  9.      pizza = new Pizza();
  10.    }
  11.     public abstract void addDough();
  12.     public abstract void addCheese();
  13.     public abstract void addHam();
  14.     public abstract void addVegetable();
  15.     public abstract void addFruit();
  16.     public abstract void addSauce();
  17.     public abstract void addToppings();
  18. }
  19.  
Konkretna klasa budownczego:
  1. public class HawaiiPizzaBuilder extends PizzaBuilder {
  2.     public void addDough() {
  3.                 getPizza().setDough("thin crust");
  4.         };
  5.     public void addCheese() {
  6.                 getPizza().setCheese("Ementaler");
  7.         }
  8.     public void addHam() {
  9.                 getPizza().setHam("Salami");         
  10.         }
  11.     public void addVegetable() {};
  12.     public void addFruit() {
  13.                 getPizza().setFruit("Pineapple");
  14.         }
  15.     public void addSauce() {
  16.                 getPizza().setSauce("tomato puree");
  17.         }
  18.     public void addToppings() {
  19.                 getPizza().setToppings("basil and oregano");
  20.         };     
  21. }
  22.  
Director (kierownik) który zarządza obiektem budowniczego:
  1. public class Cook {
  2.     private PizzaBuilder pizzaBuilder;
  3.  
  4.     public void setHouseBuilder (PizzaBuilder pizzaBuilder) {
  5.         this.pizzaBuilder = pizzaBuilder;
  6.     }
  7.  
  8.     public void buildPizza() {
  9.         pizzaBuilder.addDough();
  10.         pizzaBuilder.addCheese();
  11.         pizzaBuilder.addHam();
  12.         pizzaBuilder.addVegetable();
  13.         pizzaBuilder.addFruit();
  14.         pizzaBuilder.addSauce();
  15.         pizzaBuilder.addToppings();
  16.     }
  17.  
  18.     public House getPizza(){
  19.         return pizzaBuilder.getPizza();
  20.     }
  21. }
  22.  


B) Budowniczy metoda łańcuchowa
Mamy klasę Pizza którą chcemy tworzyć, i aby była niezmienna (immutable):
  1. package pl.edu.java.designpatterns.builder;
  2.  
  3. public class Pizza {
  4.         private String dough;
  5.         private String cheese;
  6.         private String ham;
  7.         private String vegetable;
  8.         private String sauce;
  9.         private String toppings;
  10.        
  11.         public String getDough() {
  12.                 return dough;
  13.         }
  14.         public String getCheese() {
  15.                 return cheese;
  16.         }
  17.         public String getHam() {
  18.                 return ham;
  19.         }
  20.         public String getVegetable() {
  21.                 return vegetable;
  22.         }
  23.         public String getSauce() {
  24.                 return sauce;
  25.         }
  26. }
  27.  
tworzymy naszego budowniczego wewnątrz klasy Pizza (wewnętrzna klasa):
  1. public class Pizza {
  2. .....
  3.         public static class Builder {
  4.                 private String dough;
  5.                 private String cheese;
  6.                 private String ham;
  7.                 private String vegetable;
  8.                 private String sauce;
  9.  
  10.                 public Builder(String dough, String cheese) {  // to są wymagane parametry
  11.                         this.dough = dough;
  12.                         this.cheese = cheese;
  13.                 }
  14.                
  15.                 public Builder ham(String ham) {
  16.                         this.ham = ham;
  17.                         return this;
  18.                 }
  19.                 public Builder vegetable(String vegetable) {
  20.                         this.vegetable = vegetable;
  21.                         return this;
  22.                 }
  23.                 public Builder sauce(String sauce) {
  24.                         this.sauce = sauce;
  25.                         return this;
  26.                 }
  27.                 public Pizza build() {
  28.                         return new Pizza(this);
  29.                 }
  30.         }
  31. ....
  32. }
  33.  
Konstruktor Builder(String ciasto, String ser) z tymi argumentami powoduje że mamy je obowiązkowe.
Jeżeli nie chcielibyśmy obowiązkowych parametrów to tworzymy konstruktor bezargumenowy:
public Builder() {}
i wszystkie parametry które możemy wybrać są opcjonalne.
Każda metoda której używamy w budowniczym zwraca this, co powoduje że możemy je użyć w jednym wywołaniu:
Pizza mojeZamowienie = new Pizza.Builder("thin crust", "Gouda cheese").ham("Salami").warzywa("corn").build();
i jeszcze pozostaje nam stworzenie konstruktora w klasie Pizza obsługującą budowniczego (Builder).
  1. public class Pizza {
  2. .....
  3.         public Pizza(Builder builder) {
  4.                 this.dough = builder.dough;  
  5.                 this.cheese = builder.cheese;
  6.                 this.ham = builder.ham;    
  7.                 this.vegetable = builder.vegetable;
  8.                 this.sauce = builder.sauce;
  9.         }
  10. ....
  11. }
  12.  
Zobaczmy ostateczną wersję klasy Pizza z budowniczym:
  1. package pl.edu.java.designpatterns.builder;
  2.  
  3. public class Pizza {
  4.         public static class Builder {
  5.                 private String dough;
  6.                 private String cheese;
  7.                 private String ham;
  8.                 private String vegetable;
  9.                 private String sauce;
  10.  
  11.                 public Builder(String dough, String cheese) {  // to są wymagane parametry
  12.                         this.dough = dough;
  13.                         this.cheese = cheese;
  14.                 }
  15.                
  16.                 public Builder ham(String ham) {
  17.                         this.ham = ham;
  18.                         return this;
  19.                 }
  20.                 public Builder vegetable(String vegetable) {
  21.                         this.vegetable = vegetable;
  22.                         return this;
  23.                 }
  24.                 public Builder sauce(String sauce) {
  25.                         this.sauce = sauce;
  26.                         return this;
  27.                 }
  28.                 public Pizza build() {
  29.                         return new Pizza(this);
  30.                 }
  31.         }
  32.        
  33.         private String dough;
  34.         private String cheese;
  35.         private String ham;
  36.         private String vegetable;
  37.         private String sauce;
  38.         private String toppings;
  39.        
  40.         public Pizza(Builder builder) {
  41.                 this.dough = builder.dough;  
  42.                 this.cheese = builder.cheese;
  43.                 this.ham = builder.ham;    
  44.                 this.vegetable = builder.vegetable;
  45.                 this.sauce = builder.sauce;
  46.         }
  47.  
  48.         public String getDough() {
  49.                 return dough;
  50.         }
  51.         public String getCheese() {
  52.                 return cheese;
  53.         }
  54.         public String getHam() {
  55.                 return ham;
  56.         }
  57.         public String getVegetable() {
  58.                 return vegetable;
  59.         }
  60.         public String getSauce() {
  61.                 return sauce;
  62.         }
  63.        
  64.         public static void main(String[] args) {
  65.                 Pizza firstPizza = new Pizza.Builder("thin crust", "Gouda cheese").ham("salami").vegetable("corn").build();
  66.                
  67.                 System.out.println("Pizza 1:" + firstPizza.getDough()
  68.                   + " " + firstPizza.getCheese()
  69.                   + " " + firstPizza.getHam()
  70.                   + " " + firstPizza.getVegetable()
  71.                   + " " + firstPizza.getSauce());
  72.                
  73.                 Pizza.Builder builder = new Pizza.Builder("thick crust", "Mozzarella cheese");
  74.                 builder.ham("Peperoni").sauce("garlic sauce");
  75.                 Pizza secondPizza = builder.build();
  76.  
  77.                 System.out.println("Pizza 2:" + secondPizza.getDough()
  78.                   + " " + secondPizza.getCheese()
  79.                   + " " + secondPizza.getHam()
  80.                   + " " + secondPizza.getVegetable()
  81.                   + " " + secondPizza.getSauce());
  82.                
  83.         }
  84. }
  85.  
6. Zastosowanie w kodzie java:
- java.lang.StringBuilder#append() (unsynchronized)
- java.lang.StringBuffer#append() (synchronized)

  1.  StringBuilder builder = new StringBuilder();
  2.  builder.append("To jest moje równanie: ");
  3.  builder.append(2);
  4.  builder.append("+");
  5.  builder.append(8);
  6.  builder.append("=");
  7.  builder.append(10);
  8.  builder.append(".");
  9.  System.out.println(builder.toString());
  10.  
- Locale.Builder - Budowniczy metoda łańcuchowa
- java.nio.ByteBuffer#put() (również CharBuffer, ShortBuffer, IntBuffer, LongBuffer, FloatBuffer i DoubleBuffer)
- javax.swing.GroupLayout.Group#addComponent()
- wszystkie implementacje: java.lang.Appendable.
created by madprojects.it © 2026 All Rights Reserved.